home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / comm / misc / avmnfaxsrc1_33.lha / apack.asm next >
Assembly Source File  |  1994-05-25  |  7KB  |  257 lines

  1. ;; $Id: apack.asm,v 1.2 1993/06/11 16:33:37 Rhialto Exp $
  2. ;; $Log: apack.asm,v $
  3. ;; Revision 1.2  1993/06/11  16:33:37  Rhialto
  4. ;; First real RCS checkin
  5. ;;
  6.  
  7. ****************************************************************
  8. *
  9. *  Copyright 1988 by CREATIVE FOCUS.  This code is freely
  10. *  distributable as long as this notice is retained and no
  11. *  other conditions are imposed upon its redistribution.
  12. *
  13. *
  14. *  APACK.ASM --
  15. *
  16. *  A fully compatible replacement for Electronic Arts' PACKER.C
  17. *  routine.  Converts data according to the IFF ILBM cmpByteRun1
  18. *  compression protocol:
  19. *
  20. *     control bytes:
  21. *
  22. *     n =  0.. 127:     followed by n+1 bytes of data;
  23. *     n = -1..-127:     followed by byte to be repeated -n+1 times;
  24. *     n =     -128:     don't do no nada.
  25. *
  26. *     calling format:
  27. *
  28. *     long packrow(from, too, amt)
  29. *        char **from, /* pointer to source data pointer */
  30. *         **too;  /* pointer to destination data pointer */
  31. *        long amt;     /* number of bytes to compress */
  32. *
  33. *     return(number of bytes written to destination);
  34. *
  35. *     effects:
  36. *
  37. *      *from = *from + amt, and *too = *too + return;
  38. *      return is "smart," that is, not greater than
  39. *      MaxPackedSize = amt + ((amt+127) >> 7).
  40. *
  41. *     By commenting out CHECK (below) you disable checking for runs
  42. *     exceeding 128 bytes.  That CHECK is not needed if you are sure
  43. *     the amt to be compressed is always 128 or less.
  44. *
  45. *  !!! DISCLAIMER !!!  You use this code entirely at your own
  46. *  risk.  I don't warrantee its fitness for any purpose.  I
  47. *  can't even guarantee the accuracy of anything I've said
  48. *  about it, though I've tried my damndest to get it right.
  49. *  I may, in fact, be completely out of my tiny little mind :-).
  50. *
  51. *  That being said, I can be reached for questions, comments,
  52. *  or concerns at:
  53. *
  54. *     Dr. Gerald Hull
  55. *     CREATIVE FOCUS
  56. *     12 White Street
  57. *     Binghamton, N.Y.  13901
  58. *     (607) 648-4082
  59. *
  60. *     bix:     ghull
  61. *     PLink:  DRJERRY
  62. *
  63. ***************************************************************
  64.  
  65.       section apack
  66.  
  67.       xdef  _PackRow
  68.  
  69. PT    equr  a0              -> beginning of replicate run (if any)
  70. IX    equr  a1              -> end+1 of input line
  71. IP    equr  a2              -> beginning of literal run (if any)
  72. IQ    equr  a3              -> end+1 of lit and/or rep run (if any)
  73. OP    equr  a4              -> end+1 of output line current pos
  74. FP    equr  a6              frame pointer
  75. SP    equr  a7              stack pointer
  76.  
  77. RT    equr  d0              return value
  78. MX    equr  d1              check for maximum run = MAX
  79. AM    equr  d2              amount
  80. CH    equr  d3              character
  81.  
  82. REGS  reg   AM/CH/IP/IQ/OP
  83.  
  84. FRM   equ   8              input line address
  85. TOO   equ   12              output line address
  86. AMT   equ   16              length of input line
  87.  
  88. MAX   equ   128           maximum encodable output run
  89. CHECK equ   1              turns on maximum row checking
  90.  
  91.  
  92. _PackRow
  93.  
  94.  
  95. ***************     CASE 0:   GRAB PARAMS & INITIALIZE
  96. CAS0
  97.       link     FP,#0
  98.       movem.l  REGS,-(SP)
  99.       movea.l  FRM(FP),IP
  100.       movea.l  (IP),IP        IP = *from
  101.       movea.l  IP,IQ          IQ = IP
  102.       movea.l  IQ,IX
  103.       adda.l   AMT(FP),IX     IX = IP + amt
  104.       movea.l  TOO(FP),OP
  105.       movea.l  (OP),OP        OP = *too
  106.  
  107.  
  108. ***************     CASE 1:   LITERAL RUN
  109. CAS1
  110.       movea.l  IQ,PT          adjust PT (no replicates yet!)
  111.       move.b   (IQ)+,CH       grab character
  112.       cmpa.l   IQ,IX          if input is finished
  113.       beq.s    CAS5         branch to case 5
  114.  
  115.       ifd      CHECK
  116.       move.l   IQ,MX
  117.       sub.l    IP,MX
  118.       cmpi     #MAX,MX          if run has reached MAX
  119.       beq.s    CAS6         branch to case 6
  120.       endc
  121.  
  122.       cmp.b    (IQ),CH        if next character != CH
  123.       bne.s    CAS1         stay in case 1
  124.  
  125. *                  else fall into case 2
  126.  
  127.  
  128. ***************     CASE 2:   AT LEAST 2 BYTE REPEAT
  129. CAS2
  130.       move.b   (IQ)+,CH       grab character
  131.       cmpa.l   IQ,IX          if input is finished
  132.       beq.s    CAS7         branch to case 7
  133.  
  134.       ifd      CHECK
  135.       move.l   IQ,MX
  136.       sub.l    IP,MX
  137.       cmpi     #MAX,MX          if run has reached MAX
  138.       beq.s    CAS6         branch to case 6
  139.       endc
  140.  
  141.       cmp.b    (IQ),CH        if next character != CH
  142.       bne.s    CAS1         branch to case 1
  143.  
  144. *                  else fall into case 3
  145.  
  146.  
  147. ***************     CASE 3:   REPLICATE RUN
  148. CAS3
  149.       move.b   (IQ)+,CH       grab character
  150.       cmpa.l   IQ,IX          if input is finished
  151.       beq.s    CAS7         branch to case 7
  152.  
  153.       ifd      CHECK
  154.       move.l   IQ,MX
  155.       sub.l    PT,MX
  156.       cmpi     #MAX,MX          if run has reached MAX
  157.       beq.s    CAS4         branch to case 4
  158.       endc
  159.  
  160.       cmp.b    (IQ),CH        if next character = CH
  161.       beq.s    CAS3         stay in case 3
  162.  
  163. *                  else fall into case 4
  164.  
  165.  
  166. ***************     CASE 4:   LIT AND/OR REP DUMP & CONTINUE
  167. CAS4
  168.       move.l   PT,AM
  169.       sub.l    IP,AM          AM = PT - IP
  170. *                  if no literal run
  171.       beq.s    C41         branch to replicate run
  172.  
  173.       subq     #1,AM          AM = AM - 1
  174.       move.b   AM,(OP)+       output literal control byte
  175.  
  176. C40   move.b   (IP)+,(OP)+    output literal run
  177.       dbra     AM,C40
  178.  
  179. C41   move.l   PT,AM
  180.       sub.l    IQ,AM          AM = PT - IQ (negative result!)
  181.       addq     #1,AM          AM = AM + 1
  182.       move.b   AM,(OP)+       output replicate control byte
  183.       move.b   CH,(OP)+       output repeated character
  184.       movea.l  IQ,IP          reset IP
  185.       bra.s    CAS1          branch to case 1 (not done)
  186.  
  187.  
  188. ***************     CASE 5:   LITERAL DUMP & QUIT
  189. CAS5
  190.       move.l   IQ,AM
  191.       sub.l    IP,AM          AM = IQ - IP (positive result > 0)
  192.       subq     #1,AM          AM = AM - 1
  193.       move.b   AM,(OP)+       output literal control byte
  194.  
  195. C50   move.b   (IP)+,(OP)+    output literal run
  196.       dbra     AM,C50
  197.  
  198.       bra.s    CAS8          branch to case 8 (done)
  199.  
  200.  
  201.       ifd      CHECK
  202.  
  203. ***************     CASE 6:   LITERAL DUMP & CONTINUE
  204. CAS6
  205.       move.l   IQ,AM
  206.       sub.l    IP,AM          AM = IQ - IP (positive result > 0)
  207.       subq     #1,AM          AM = AM - 1
  208.       move.b   AM,(OP)+       output literal control byte
  209.  
  210. C60   move.b   (IP)+,(OP)+    output literal run
  211.       dbra     AM,C60
  212.  
  213.       bra      CAS1          branch to case 1 (not done)
  214.  
  215.       endc
  216.  
  217.  
  218. ***************     CASE 7:   LIT AND/OR REP DUMP & FINISH
  219. CAS7
  220.       move.l   PT,AM
  221.       sub.l    IP,AM          AM = PT - IP (positive result > 0)
  222. *                  if no literal run
  223.       beq.s    C71         branch to replicate run
  224.  
  225.       subq     #1,AM          AM = AM - 1
  226.       move.b   AM,(OP)+       output literal control byte
  227.  
  228. C70   move.b   (IP)+,(OP)+    output literal run
  229.       dbra     AM,C70
  230.  
  231. C71   move.l   PT,AM
  232.       sub.l    IQ,AM          AM = PT - IQ (negative result)
  233.       addq     #1,AM          AM = AM + 1
  234.       move.b   AM,(OP)+       output replicate control byte
  235.       move.b   CH,(OP)+       output repeated character
  236.  
  237. *                  fall into case 8
  238.  
  239.  
  240. ***************     CASE 8:   ADJUST PARAMS & RETURN VALUE
  241. CAS8
  242.       movea.l  FRM(FP),PT     PT = **from
  243.       move.l   IQ,(PT)        *from = *from + amt
  244.       movea.l  TOO(FP),PT     PT = **too
  245.  
  246.       move.l   OP,RT
  247.       sub.l    (PT),RT       return = OP - *too
  248.  
  249.       move.l   OP,(PT)       *too = *too + return
  250.       movem.l  (SP)+,REGS
  251.       UNLK     FP
  252.       rts
  253.  
  254.       end
  255.  
  256.  
  257.